package com.hancher.gamelife2.menstrual;

import android.os.Bundle;

import androidx.navigation.Navigation;
import androidx.sqlite.db.SimpleSQLiteQuery;

import com.github.gzuliyujiang.wheelpicker.entity.DateEntity;
import com.haibin.calendarview.Calendar;
import com.haibin.calendarview.CalendarView;
import com.hancher.common.androidutil.AsyncUtils;
import com.hancher.common.androidutil.LogUtil;
import com.hancher.common.androidutil.MmkvUtil;
import com.hancher.common.androidutil.ToastUtil;
import com.hancher.common.base.BaseMvpFragment;
import com.hancher.common.javautil.DateUtil;
import com.hancher.common.javautil.EmptyUtil;
import com.hancher.common.javautil.GsonUtil;
import com.hancher.common.room.DbFiliter;
import com.hancher.gamelife2.R;
import com.hancher.gamelife2.databinding.FragmentMenstrualListBinding;
import com.hancher.gamelife2.diary.DiaryPO;
import com.hancher.gamelife2.home.HomePresenter;
import com.hancher.gamelife2.main.MainDatabase_Impl;
import com.lxj.xpopup.XPopup;
import com.lxj.xpopup.impl.LoadingPopupView;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import io.reactivex.rxjava3.functions.Consumer;

/**
 * 作者 : Hancher ytu_shaoweijie@163.com <br/>
 * 时间 : 2023/3/12 0012 22:49 <br/>
 * 描述 :
 */
public class MenstrualListFragment extends BaseMvpFragment<FragmentMenstrualListBinding, HomePresenter> {


    private static final String MENSTRUAL_RECORD_NAME = "DIARY_LIST_MONTH_FILTER";
    private static final String MENSTRUAL_LIST_YEAR = "DIARY_LIST_YEAR";
    private static final String MENSTRUAL_LIST_MONTH = "DIARY_LIST_MONTH";
    DbFiliter filiter = new DbFiliter();
    /**
     * 等待数据获取完成（数据+百度缩略图）
     */
    private LoadingPopupView waitDialog;

    @Override
    protected void initView(Bundle savedInstanceState) {
        binding.tvMonthFilter.setText(MmkvUtil.getString(MENSTRUAL_RECORD_NAME, "记录人"));

        int lastYear = DateUtil.getYear();
        int lastMonth = DateUtil.getMonth();
        MmkvUtil.put(MENSTRUAL_LIST_YEAR, lastYear);
        MmkvUtil.put(MENSTRUAL_LIST_MONTH, lastMonth);
        //请求参数
        filiter.setStart(DateUtil.getFirstStampOfMonth(lastYear, lastMonth, 0));
        filiter.setEnd(DateUtil.getFirstStampOfMonth(lastYear, lastMonth, 1));
        binding.calendarView.setOnCalendarSelectListener(new CalendarView.OnCalendarSelectListener() {
            @Override
            public void onCalendarOutOfRange(Calendar calendar) {

            }

            @Override
            public void onCalendarSelect(Calendar calendar, boolean isClick) {
                MmkvUtil.put(MENSTRUAL_LIST_YEAR, calendar.getYear());
                MmkvUtil.put(MENSTRUAL_LIST_MONTH, calendar.getMonth());
                selectItem(calendar.getYear(), calendar.getMonth(), calendar.getDay());
            }
        });
        binding.calendarView.setOnMonthChangeListener(this::onMonthChange);

        //滚动时间
        binding.dateWheelLayout.setRange(DateEntity.yearOnFuture(-50), DateEntity.yearOnFuture(1));
        binding.dateWheelLayout.setDefaultValue(DateEntity.target(lastYear, lastMonth, 0));
        binding.dateWheelLayout.setOnDateSelectedListener((year, month, day) -> onMonthChange(year, month));

    }


    @Override
    protected void initListener() {
        // 点击记录人，弹出记录人选择框
        binding.tvMonthFilter.setOnClickListener(v -> {
            AsyncUtils.run(emitter -> {
                StringBuffer sql = new StringBuffer();
                Object whereArgs = null;
                sql.append(" SELECT * FROM menstrual WHERE deleteflag!=1 ");
                sql.append(" GROUP BY name ");
                LogUtil.d("sql : " + sql);
                List<MenstrualPO> data = MainDatabase_Impl.getInstance().menstrualDao().getList(new SimpleSQLiteQuery(sql.toString()));
                if (EmptyUtil.isEmpty(data)) {
                    emitter.onNext(new ArrayList<>());
                    return;
                }
                List<String> names = new ArrayList<>();
                for (MenstrualPO datum : data) {
                    String name = datum.getName();
                    names.add(name);
                }
                emitter.onNext(names);
                emitter.onComplete();

            }, (Consumer<List<String>>) data -> {
                LogUtil.d("数据库查询到数据：" + data);
                if (EmptyUtil.isEmpty(data)) {
                    ToastUtil.show("无数据，请直接添加！");
                    return;
                }
                // 选择记录人
                new XPopup.Builder(getContext())
                        .hasShadowBg(false)
                        .animationDuration(0)
                        .asCenterList("选择记录人", data.toArray(new String[data.size()]),
                                new int[]{},
                                (position, text) -> {
                                    ToastUtil.show("click " + text);
                                    MmkvUtil.put(MENSTRUAL_RECORD_NAME, text);
                                    binding.tvMonthFilter.setText(text);
                                    queryList();
                                })
                        .show();
            });
        });

        binding.tvRecord.setOnClickListener(v -> {
            Calendar selectCalendar = binding.calendarView.getSelectedCalendar();
            Long recordTime = DateUtil.getFirstStampOfDay(selectCalendar.getYear(), selectCalendar.getMonth(), selectCalendar.getDay(), 0);
            new XPopup.Builder(getContext())
                    .asCustom(new EditMenstrualDialog(getContext(), selectItemInCalendar, recordTime, updateData -> {
                        // TODO: 2024/5/5 保存或者更新数据
                        AsyncUtils.run(emitter -> {
                            if (updateData.getId() == null) {
                                MainDatabase_Impl.getInstance().menstrualDao().insertItem(updateData);
                                LogUtil.d("插入结束");
                            } else {
                                updateData.setUpdateTime(System.currentTimeMillis());
                                MainDatabase_Impl.getInstance().menstrualDao().updateItem(updateData);
                                LogUtil.d("更新结束");
                            }
                            emitter.onNext("");
                        }, o -> {
                            queryList();
                        });

                    }))
                    .show();
        });
    }

    @Override
    protected void initData() {
        queryList();
    }


    //region 查询数据

    /**
     * 月份切换，需要查询
     * @param year
     * @param month
     */
    private void onMonthChange(int year, int month) {
        int lastYear = MmkvUtil.getInt(MENSTRUAL_LIST_YEAR, DateUtil.getYear());
        int lastMonth = MmkvUtil.getInt(MENSTRUAL_LIST_MONTH, DateUtil.getMonth());
        if (year == lastYear && lastMonth == month) {
            return;
        }
        LogUtil.d("选中日期：" + year + "-" + month);

        //设置内存过滤时间
        filiter.setStart(DateUtil.getFirstStampOfMonth(year, month, 0));
        filiter.setEnd(DateUtil.getFirstStampOfMonth(year, month, 1));
        //保存mmkv过滤时间
        MmkvUtil.put(MENSTRUAL_LIST_YEAR, year);
        MmkvUtil.put(MENSTRUAL_LIST_MONTH, month);
        //更新滚轮时间
        if (binding.dateWheelLayout.getSelectedYear() != year || binding.dateWheelLayout.getSelectedMonth() != month) {
            binding.dateWheelLayout.setDefaultValue(DateEntity.target(year, month, 0));
        }
        //更新日历时间
        if (binding.calendarView.getSelectedCalendar().getYear() != year || binding.calendarView.getSelectedCalendar().getMonth() != month) {
            binding.calendarView.setSelectEndCalendar(year, month, 1);
            binding.calendarView.setSelectStartCalendar(year, month, 1);
            binding.calendarView.scrollToCalendar(year, month, 1);
        }
        //重新查询数据
        queryList();
    }

    /**
     * 查询
     */
    private void queryList() {
        waitDialog = (LoadingPopupView) new XPopup.Builder(getContext())
                .dismissOnBackPressed(false)
                .dismissOnTouchOutside(false)
                .asLoading("正在加载中")
                .show();
        binding.calendarView.setSchemeDate(new HashMap<>());
        AsyncUtils.run(emitter -> {
            StringBuffer sql = new StringBuffer();
            sql.append(" SELECT * FROM menstrual WHERE deleteflag!=1 ");
            sql.append(" AND recordTime BETWEEN ").append(filiter.getStart()).append(" AND ").append(filiter.getEnd()).append(" ");
            sql.append(" AND name='").append(MmkvUtil.getString(MENSTRUAL_RECORD_NAME, "")).append("' ");
            sql.append(" ORDER BY recordTime ");
            LogUtil.d("sql : " + sql);
            List<MenstrualPO> data = MainDatabase_Impl.getInstance().menstrualDao().getList(new SimpleSQLiteQuery(sql.toString()));
            emitter.onNext(data);
        }, (Consumer<List<MenstrualPO>>) data -> {
            if (waitDialog != null && waitDialog.isShow()) {
                waitDialog.dismiss();
            }
            if (EmptyUtil.isEmpty(data)) {
                return;
            }
            LogUtil.d("查询记录 记录条数：" + data.size());
            Map<String, Calendar> mSchemeDates = new HashMap<>();
            int continueStartDay = 1;
            for (MenstrualPO item : data) {
                Calendar calendar = new Calendar();
                calendar.setYear(DateUtil.getYear(item.getRecordTime()));
                calendar.setMonth(DateUtil.getMonth(item.getRecordTime()));
                calendar.setDay(DateUtil.getDay(item.getRecordTime()));
                calendar.setScheme("记 ");
                mSchemeDates.put(calendar.toString(), calendar);
                if (item.getStatus() == 0) {
                    continueStartDay = DateUtil.getDay(item.getRecordTime()) + 1;
                }
                if (item.getStatus() == 1) {
                    for (int i = continueStartDay; i < DateUtil.getDay(item.getRecordTime()); i++) {
                        Calendar calendar1 = new Calendar();
                        calendar1.setYear(DateUtil.getYear(item.getRecordTime()));
                        calendar1.setMonth(DateUtil.getMonth(item.getRecordTime()));
                        calendar1.setDay(i);
                        calendar1.setScheme("");
                        mSchemeDates.put(calendar1.toString(), calendar1);
                    }
                }
            }
            LogUtil.d("组织calendar " + GsonUtil.obj2JsonStr(mSchemeDates));
            binding.calendarView.setSchemeDate(mSchemeDates);
        });
    }

    //endregion

    //region 点击条目
    private void modifyDiary(DiaryPO diaryPO) {
        Bundle finalArgs = new Bundle();
        finalArgs.putString("data", diaryPO.getUuid());
        Navigation.findNavController(binding.container).navigate(R.id.action_diaryListFragment_to_diaryEditFragment, finalArgs);
    }

    private void deleteDiaryItem(DiaryPO diaryPO) {
        AsyncUtils.run(emitter -> {
            diaryPO.setUpdateTime(System.currentTimeMillis());
            diaryPO.setDeleteflag((byte) 1);
            MainDatabase_Impl.getInstance().diaryDao().updateItem(diaryPO);
            emitter.onNext("");
        }, data -> {
            queryList();
        });
    }

    MenstrualPO selectItemInCalendar = null;

    /**
     * 查询当天数据，并弹窗编辑
     * @param year
     * @param month 1-12
     * @param day
     */
    private void selectItem(int year, int month, int day) {
        AsyncUtils.run(emitter -> {
            Long endTime = DateUtil.getFirstStampOfDay(year, month, day, 1);
            Long startTime = DateUtil.getFirstStampOfDay(year, month, day, 0);
            StringBuilder sql = new StringBuilder();
            sql.append(" SELECT * FROM menstrual WHERE deleteflag!=1 ");
            sql.append(" AND recordTime BETWEEN ").append(startTime).append(" AND ").append(endTime);
            sql.append(" AND name='").append(MmkvUtil.getString(MENSTRUAL_RECORD_NAME, "")).append("' ");
            LogUtil.d("sql : " + sql);
            List<MenstrualPO> data = MainDatabase_Impl.getInstance().menstrualDao().getList(new SimpleSQLiteQuery(sql.toString()));
            if (EmptyUtil.isEmpty(data)) {
                emitter.onNext(new MenstrualPO());
                return;
            }
            emitter.onNext(data.get(0));
            emitter.onComplete();

        }, (Consumer<MenstrualPO>) data -> {
            LogUtil.d("数据库查询到数据：" + data);
            if (data.getRecordTime() == null) {
                selectItemInCalendar = null;
                binding.tvRecord.setText("无记录");
            } else {
                selectItemInCalendar = data;
                String text = String.format("姓名: %s\n状态: %s\n备注: %s", data.getName(), data.getStatus() == 0 ? "开始" : "结束", data.getDescription());
                binding.tvRecord.setText(text);
            }
        });
    }
    //endregion
}